//------------------------------------------------------------------
//  BIGINTEC.h
//------------------------------------------------------------------
//                      y^2 = x^3 + a*x + b                             
//------------------------------------------------------------------
//  Curve
//------------------------------------------------------------------
typedef struct 
{
        BIGINT  a;
		BIGINT  b;
} BIGINT_CURVE;
//------------------------------------------------------------------
//  coordinates for a point
//------------------------------------------------------------------
typedef struct 
{
        BIGINT  x;
        BIGINT  y;
} BIGINT_POINT;
//------------------------------------------------------------------
//  Curve and Base Point
//------------------------------------------------------------------
typedef struct
{
	BIGINT_CURVE curv;
	BIGINT_POINT basep;
} BIGINT_EC_PARAMETER;
//------------------------------------------------------------------
//  point calculation in integer domain
//------------------------------------------------------------------
void bigint_eneg(BIGINT_POINT* p);
void bigint_copy_point(BIGINT_POINT* p1, BIGINT_POINT* p2);
void bigint_esum(BIGINT_POINT* p1, BIGINT_POINT* p2, BIGINT_POINT* p3, BIGINT_CURVE* curv);
void bigint_edbl(BIGINT_POINT* p1, BIGINT_POINT* p3, BIGINT_CURVE* curv);
void bigint_esub(BIGINT_POINT* p1, BIGINT_POINT* p2, BIGINT_POINT* p3, BIGINT_CURVE* curv);
void bigint_emul(BIGINT* k, BIGINT_POINT* p, BIGINT_POINT* r, BIGINT_CURVE* curv);

void my_bigint_ladder(BIGINT* x1, BIGINT* z1, BIGINT* x2, BIGINT* z2,BIGINT* x, BIGINT_CURVE* curv);
void my_bigint_ladder13(BIGINT* x1, BIGINT* z1, BIGINT* x2, BIGINT* z2,BIGINT* x, BIGINT_CURVE* curv);
void my_bigint_ladderp(BIGINT* x1, BIGINT* z1, BIGINT* x2, BIGINT* z2,BIGINT* x, BIGINT_CURVE* curv);
void my_bigint_edbl(BIGINT* X1_pro, BIGINT* Y1_pro,  BIGINT* Z1_pro, BIGINT* X3, BIGINT* Y3, BIGINT* Z3 ,BIGINT_CURVE* curv);
void my_bigint_esum(BIGINT* X1_pro, BIGINT* Y1_pro,  BIGINT* Z1_pro, BIGINT* X2_pro, BIGINT* Y2_pro, BIGINT* Z2_pro , BIGINT* X3, BIGINT* Y3, BIGINT* Z3,BIGINT_CURVE* curv );
void my_bigint_emul(BIGINT* k, BIGINT_POINT* p, BIGINT_POINT* r, BIGINT_CURVE* curv);

//------------------------------------------------------------------
// point calculation in Montgomery domain
//------------------------------------------------------------------
void bigint_mon_eneg(BIGINT_POINT* p);
void bigint_mon_copy_point(BIGINT_POINT* p1, BIGINT_POINT* p2);
void bigint_mon_esum(BIGINT_POINT* p1, BIGINT_POINT* p2, BIGINT_POINT* p3, BIGINT_CURVE* curv);
void bigint_mon_edbl(BIGINT_POINT* p1, BIGINT_POINT* p3, BIGINT_CURVE* curv);
void bigint_mon_esub(BIGINT_POINT* p1, BIGINT_POINT* p2, BIGINT_POINT* p3, BIGINT_CURVE* curv);
void bigint_mon_emul_LtoR(BIGINT* k, BIGINT_POINT* p, BIGINT_POINT* r, BIGINT_CURVE* curv);
//------------------------------------------------------------------
// point calculation by Double-and-Add-Always (Right-to-Left)
//------------------------------------------------------------------
void bigint_emul_LtoR(BIGINT* k, BIGINT_POINT* p, BIGINT_POINT* r, BIGINT_CURVE* curv);

void p_to_q(BIGINT* x, BIGINT* y);
